﻿using System;
using System.Collections.Generic;
using System.Drawing;
using System.Linq;
using System.Text;

namespace DesertKharonIrcPlugin
{
    public enum EndTokenNotFoundAction
    { 
        Null,
        StartTokenToStringEnd
    }

    public static class StringExtensionMethods
    {
        public static bool IsLike(this String value, String other)
        {
            if (!String.IsNullOrWhiteSpace(value))
            {
                if (!String.IsNullOrWhiteSpace(other))
                    return value.ToLower().Trim() == other.ToLower().Trim();
                else
                    return false;
            }
            else
                return String.IsNullOrWhiteSpace(other);
        }

        public static string Extract(this String value, string startToken, string endToken)
        {
            int nextStartIndex = 0;
            return Extract(value, startToken, endToken, EndTokenNotFoundAction.Null, 0, out nextStartIndex);
        }

        public static string Extract(this String value, string startToken, string endToken, EndTokenNotFoundAction endTokenNotFoundAction)
        {
            int nextStartIndex = 0;
            return Extract(value, startToken, endToken, endTokenNotFoundAction, 0, out nextStartIndex);
        }

        public static string Extract(this String value, string startToken, string endToken, EndTokenNotFoundAction endTokenNotFoundAction, int startIndex)
        {
            int nextStartIndex = 0;
            return Extract(value, startToken, endToken, endTokenNotFoundAction, startIndex, out nextStartIndex);
        }

        public static string Extract(this String value, string startToken, string endToken, EndTokenNotFoundAction endTokenNotFoundAction, int startIndex, out int nextStartIndex)
        {
            nextStartIndex = -1;

            #region validate params
            if (startIndex < 0)
                throw new ArgumentException("startIndex", "Value can't be less then 0.");

            if (String.IsNullOrWhiteSpace(value))
                return null;

            if (startIndex > value.Length - 1)
                return null;

            if (startToken != null)
            {
                if (String.IsNullOrEmpty(startToken))
                    startToken = null;
            }

            if (endToken != null)
            {
                if (String.IsNullOrEmpty(endToken))
                    endToken = null;
            }

            if (startToken == null && endToken == null)
                return value.Substring(startIndex);

            #endregion

            int valueStartIndex = startIndex;
            if (startToken != null)
            {
                valueStartIndex = value.IndexOf(startToken, startIndex);
                if (valueStartIndex > -1)
                {
                    valueStartIndex += startToken.Length;
                    if (valueStartIndex >= value.Length)
                        return null;
                }
                else
                    return null;
            }

            if (endToken != null)
            {
                int valueEndIndex = value.IndexOf(endToken, valueStartIndex);
                if (valueEndIndex > -1)
                {
                    if (valueEndIndex + endToken.Length < value.Length)
                        nextStartIndex = valueEndIndex + endToken.Length;

                    return value.Substring(valueStartIndex, valueEndIndex - valueStartIndex);
                }
                else
                {
                    if (endTokenNotFoundAction == EndTokenNotFoundAction.Null)
                        return null;
                }
            }

            return value.Substring(valueStartIndex);
        }

        public static List<string> ExtractList(this String value, string startToken, string endToken)
        {
            return ExtractList(value, startToken, endToken, 0, StringSplitOptions.None);
        }

        public static List<string> ExtractList(this String value, string startToken, string endToken, int startIndex)
        {
            return ExtractList(value, startToken, endToken, startIndex, StringSplitOptions.None);
        }

        public static List<string> ExtractList(this String value, string startToken, string endToken, StringSplitOptions stringSplitOptions)
        {
            return ExtractList(value, startToken, endToken, 0, stringSplitOptions);
        }

        public static List<string> ExtractList(this String value, string startToken, string endToken, int startIndex, StringSplitOptions stringSplitOptions)
        {
            List<string> resultList = new List<string>();

            int nextStartIndex = 0;
            while (nextStartIndex != -1)
            {
                string result = value.Extract(startToken, endToken, EndTokenNotFoundAction.Null, nextStartIndex, out nextStartIndex);
                if (result != null)
                    resultList.Add(result);
            }

            if (stringSplitOptions == StringSplitOptions.RemoveEmptyEntries)
                return resultList.Where(e => !String.IsNullOrWhiteSpace(e)).ToList();

            return resultList;
        }

        public static SizeF Measure(this string value, Font font)
        {
            SizeF result;
            using (Bitmap bitmap = new Bitmap(1, 1))
            {
                using (Graphics graphics = Graphics.FromImage(bitmap))
                {
                    result = graphics.MeasureString(value, font);
                }
            }

            return result;
        }

        public static bool IsInt(this string value)
        {
            if (!String.IsNullOrWhiteSpace(value))
            {
                foreach (char c in value)
                {
                    if (c < '0' || c > '9')
                        return false;
                }

                return true;
            }

            return false;
        }

        public static bool DirectoryPathEndsWith(this string path, string ending, bool ignoreCase = true)
        {
            if (!String.IsNullOrWhiteSpace(path) && !String.IsNullOrWhiteSpace(ending))
            {
                if (ignoreCase)
                {
                    string lowerCasePath = path.ToLower();
                    string lowerCaseEnding = path.ToLower();

                    if (lowerCasePath.Contains(lowerCaseEnding + "\\"))
                        return true;

                    if (lowerCasePath.Contains(lowerCaseEnding + "/"))
                        return true;

                    if (lowerCasePath.Contains(lowerCaseEnding))
                        return true;
                }
                else
                {
                    if (path.Contains(ending + "\\"))
                        return true;

                    if (path.Contains(ending + "/"))
                        return true;

                    if (path.Contains(ending))
                        return true;
                }
            }
            else if (String.IsNullOrWhiteSpace(path) && String.IsNullOrWhiteSpace(ending))
                return true;

            return false;
        }
    }
}
